home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / 4p_v331.zip / STAT.API < prev    next >
Text File  |  1996-06-01  |  12KB  |  210 lines

  1.  
  2.  Description of the STAT.386 API                         v3.3.1 from 01.06.1996
  3.  ===============================                         STAT.386 driver v01.03
  4.  
  5.  The file contains a description of the STAT.386 API (Application Program[ming]
  6.  Interface) and some programming examples for it.
  7.  
  8.  
  9.  1.  Introduction
  10.  ================
  11.  
  12.  The STAT.386 driver was written by Ton Plooy (tonp@xs4all.nl) in December 1995
  13.  to make STAT.EXE runs under MS-Windows 3.1 or MS-Windows 95 too. To be able to
  14.  execute some iPentium-specific instructions, like RDTSC, RDMSR and WRMSR, your
  15.  code needs to run at CPL=0 (Code Privilege Level #0), to avoid exceptioms from
  16.  these instructions, listed above.
  17.  
  18.  Because the DOS box under MS-Windows 3.1 or MS-Windows 95 runs at CPL=3 (which
  19.  is the lowest privilege level), you can't execute a RDMSR or WRMSR instruction
  20.  in the DOS box. This causes an exception and MS-Windows will close the DOS box
  21.  then. So you need -- somehow -- access to CPL=0.
  22.  
  23.  Outside the MS-Windows DOS box STAT.EXE will use the VCPI API (Virtual Control
  24.  Program[ming] Interface), to enter CPL=0, execute the iPentium-specific RDTSC,
  25.  RDMSR or WRMSR instructions, and to return to CPL=3. (The VCPI API is provided
  26.  by most EMM386 drivers, as EMM386.EXE, QEMM386.SYS etc. If you load one of the
  27.  EMM386 drivers, then the driver kernel runs at CPL=0, to have the full control
  28.  over your machine, and your 'DOS command line' runs at CPL=3. So the processor
  29.  runs in virtual 8086 mode then.)
  30.  
  31.  The STAT.386 driver is a MS-Windows VxD. On start up MS-Windows loads all VxDs
  32.  which are listed in the SYSTEM.INI file, section [386Enh]. There you will find
  33.  entries like 'DEVICE=x:\path\STAT.386'. Most VxDs contain an API, which can be
  34.  used by applications. And VxDs may contain code, which runs at CPL=0. So a VxD
  35.  is the key to CPL=0 under MS-Windows 3.1 or MS-Windows 95. (Another way is the
  36.  modification of the GDT (Global Descriptor Table). This table is not protected
  37.  by MS-Windows 3.1 or MS-Windows 95. So you could include a Call Gate into this
  38.  GDT and use it to enter CPL=0.)
  39.  
  40.  So the STAT.386 driver provides an API for STAT.EXE and all other programs, to
  41.  execute the RDTSC, RDMSR and WRMSR instruction under MS-Windows 3.1 or MS-Win-
  42.  dows 95. The driver is only neccessary, when MS-Windows runs in enhanced mode,
  43.  because (a) VxDs are not used in standard mode and (b) MS-Windows will not use
  44.  its own virtual mode kernel in standard mode. (So if you run standard mode and
  45.  an EMM386 driver, then the VCPI API can be used from inside a DOS box too. But
  46.  if you run enhanced mode and an EMM386 driver, then the MS-Windows kernel will
  47.  replace the EMM386 driver's virtual mode kernel, and so the VCPI is disabled.)
  48.  
  49.  
  50.  2.  The API
  51.  ===========
  52.  
  53.  First you must check, whether the INT 2Fh is handled by someone, or not. After
  54.  this check you can try to get the VxD entry point:
  55.  
  56.  ------------------------------------------------------------------------------
  57.  in:     AX=1684h          function 'Get VxD Entry Point'
  58.          BX=37DEh          final unique VxD ID (assigned by Microsoft)
  59.          ES:DI=0000:0000h  clear pointer for VxD entry point
  60.  use:    INT 2Fh           call multiplex interrupt
  61.  out:    ES:DI=xxxx:xxxxh  VxD entry point
  62.  ------------------------------------------------------------------------------
  63.  
  64.  If ES:DI returns not 0000:0000h, then the VxD is active (and so MS-Windows 3.1
  65.  or MS-Windows 95 runs in enhanced mode). So you can call this entry point then
  66.  for the following functions:
  67.  
  68.  ------------------------------------------------------------------------------
  69.  in:     AX=0000h          function 'Get STAT.386 Version'
  70.  use:    call entry point  call STAT.386 entry point
  71.  out:    AX=xxyyh          STAT.386 version xx.yy
  72.  rem:    This function returns the internal STAT.386 driver version. The future
  73.          versions may have a different API. So do check for the correct version
  74.          before you call any function above 0000h!
  75.  ------------------------------------------------------------------------------
  76.  in:     AX=0001h          function 'Execute RDTSC, RDMSR or WRMSR'
  77.          BX=00xxh          2nd opcode byte (30h, 31h or 32h)
  78.          EDX:EDI=64 bit    input value for WRMSR
  79.          ECX=32 bit        MSR number for RDMSR or WRMSR
  80.  use:    call entry point  call STAT.386 entry point
  81.  out:    EDX:EAX=64 bit    output value from RDTSC or RDMSR
  82.  rem:    This function executes the RDTSC, RDMSR or WRMSR instruction. Load the
  83.          2nd opcode byte to BL (30h=WRMSR, 31h=RDTSC, 32h=RDMSR), the MSR # for
  84.          RDMSR or WRMSR to ECX and the MSR value for WRMSR to EDX:EDI.
  85.          The TSC or MSR value is returned in EDX:EAX. All unused register parts
  86.          should contain zero.
  87.  ------------------------------------------------------------------------------
  88.  in:     AX=0002h..FFFFh   reserved for future use
  89.  use:    call entry point  call STAT.386 entry point
  90.  out:    nothing           reserved for future use
  91.  rem:    All functions above 0001h are reserved for future use. Do not use them
  92.          at the moment, because this may cause trouble.
  93.  ------------------------------------------------------------------------------
  94.  
  95.  Attention! This API layout may be changed with future versions of the STAT.386
  96.  driver. Only function 0000h is guaranteed to stay stable.
  97.  
  98.  
  99.  3.  Programming Example
  100.  =======================
  101.  
  102.  The following Turbo/Borland Pascal unit is used by STAT.EXE to handle the VxD.
  103.  
  104.  ------------------------------------------------------------------------------
  105.  Unit CL_VxD;                                           {uses the STAT.386 VxD}
  106.  
  107.  INTERFACE                                              {exported stuff}
  108.  Const     VxD_ID          : Word      = $37DE;         {final VxD ID value}
  109.            VxD_Ver_W       : Word      = $0103;         {actual VxD version}
  110.            VxD_Ver_S       : String[4] = '1.03';        {actual VxD version}
  111.  Function  Check_VxD       : Pointer;                   {the install check}
  112.  Function  Get_VxD_Version : Word;                      {the installed version}
  113.  Procedure CPL0_VxD(B1:Byte; B2:Word;                   {the procedure itself}
  114.                     Var W4,W3,W2,W1:Word);
  115.  
  116.  IMPLEMENTATION                                         {internal stuff}
  117.  Uses DOS;                                              {for some INT stuff}
  118.  Var  CPU         : Registers;                          {for some INT stuff}
  119.       Entry_VxD   : Pointer;                            {for VxD entry point}
  120.       a_Procedure : Procedure;                          {a dummy procedure}
  121.  
  122.  { The following function checks, whether the INT 2Fh is handled or not. Then }
  123.  { it checks, whether the STAT.386 is loaded or not, and if it's loaded, then }
  124.  { returns the VxD entry point.                                               }
  125.  
  126.  Function Check_VxD:Pointer;                            {the install check}
  127.  Var Int2F : Pointer;                                   {for INT 2Fh handler}
  128.  Begin
  129.    GetIntVec($2F,Int2F);                                {get INT 2Fh handler}
  130.    Check_VxD:=NIL;                                      {assume no VxD}
  131.    If Int2F<>NIL Then Begin                             {if INT 2Fh is handled}
  132.      CPU.AX:=$1684;                                     {function 'Get API'}
  133.      CPU.BX:=VxD_ID;                                    {signature "STAT.386"}
  134.      CPU.DI:=$0000;                                     {prepare VxD entry}
  135.      CPU.ES:=$0000;                                     {ES:DI->0000:0000}
  136.      INTR($2F,CPU);                                     {call multiplex INT}
  137.      Check_VxD:=Ptr(CPU.ES,CPU.DI);                     {return VxD entry}
  138.    End;
  139.  End;
  140.  
  141.  { The following function returns an internal STAT.386 VxD version. If no VxD }
  142.  { is installed, then it returns 0000h for the version. The value 0100h would }
  143.  { indicate a version 01.00 for STAT.386.                                     }
  144.  
  145.  Function  Get_VxD_Version:Word;                        {the installed version}
  146.  Var Version:Word;